package com.hwpt.chesedemo.presentation.viewmodel

import android.util.Log
import com.hwpt.chesedemo.presentation.theme.StringResources
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.hwpt.chesedemo.presentation.component.ChessPiece
import com.hwpt.chesedemo.presentation.component.PieceType
import com.hwpt.chesedemo.presentation.component.Player
import com.hwpt.chesedemo.presentation.component.Position
import com.hwpt.chesedemo.data.remote.llm.AiService
import com.hwpt.chesedemo.data.local.entity.GameRecordEntity
import com.hwpt.chesedemo.data.local.repository.ChessRepository
import com.hwpt.chesedemo.presentation.theme.AppStrings
import com.hwpt.chesedemo.presentation.theme.LanguageManager
import com.hwpt.chesedemo.data.remote.llm.PromptTemplates
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class AnalysisViewModel @Inject constructor(
    private val repository: ChessRepository,
    private val aiService: AiService
) : ViewModel() {

    var state by mutableStateOf(AnalysisState())
        private set

    // 存储解析后的所有棋盘状态
    private var allBoardStates: List<List<List<ChessPiece?>>> = emptyList()
    private var allMoves: List<ChessMove> = emptyList()

    // 当前语言环境的字符串资源
    private val currentStrings: StringResources
        get() = AppStrings.getByLanguageCode(LanguageManager.currentLanguageCode)

    init {
        loadGameRecords()
    }

    private fun loadGameRecords() {
        viewModelScope.launch {
            repository.getSavedGames().collectLatest { records ->
                // 转换记录中的AI难度名称和游戏结果
                val translatedRecords = records.map { record ->
                    record.copy(
                        aiDifficulty = translateDifficultyName(record.aiDifficulty ?: ""),
                        // 翻译游戏结果
                        result = translateGameResult(record.result ?: "")
                    )
                }
                state = state.copy(gameRecords = translatedRecords)
            }
        }
    }

    /**
     * 将中文难度名称转换为当前语言的难度名称
     */
    private fun translateDifficultyName(chineseName: String): String {
        return AppStrings.translateDifficultyName(chineseName, currentStrings)
    }

    /**
     * 将游戏结果转换为当前语言
     */
    private fun translateGameResult(result: String): String {
        return AppStrings.translateGameResult(result, currentStrings)
    }

    fun onInputMethodSelected(method: InputMethod) {
        state = state.copy(selectedInputMethod = method)
        updateAnalyzeButtonState()
    }

    fun onRecordSelected(record: GameRecordEntity) {
        // 确保选中的记录也已转换难度名称和游戏结果
        val translatedRecord = record.copy(
            aiDifficulty = translateDifficultyName(record.aiDifficulty ?: ""),
            result = translateGameResult(record.result ?: "")
        )
        state = state.copy(selectedRecord = translatedRecord)
        updateAnalyzeButtonState()
    }

    fun onPgnTextChanged(text: String) {
        state = state.copy(pgnText = text)
        updateAnalyzeButtonState()
    }

    fun onAnalyze() {
        state = state.copy(isLoading = true)

        viewModelScope.launch {
            try {
                // 解析PGN并生成所有棋盘状态
                val pgn = when (state.selectedInputMethod) {
                    InputMethod.RECORD -> state.selectedRecord?.pgn ?: ""
                    InputMethod.TEXT -> state.pgnText
                }

                if (pgn.isBlank()) {
                    state = state.copy(
                        isLoading = false,
                        errorMessage = currentStrings.pastePgnFormat
                    )
                    return@launch
                }

                // 解析PGN并生成所有棋盘状态
                allBoardStates = parsePGNToBoardStates(pgn)
                allMoves = parsePGNToMoves(pgn)

                // 调用AI分析
                val analysisResults = performAiAnalysis(pgn, allMoves)

                state = state.copy(
                    isLoading = false,
                    showChessboard = true,
                    showAnalysis = true,
                    analysisResults = analysisResults,
                    moves = analysisResults,
                    currentBoardState = if (allBoardStates.isNotEmpty()) allBoardStates[0] else createInitialBoard(),
                    currentMoveIndex = 0,
                    highlightedMoveIndex = 0, // 初始高亮第一步
                    errorMessage = null
                )
            } catch (e: Exception) {
                state = state.copy(
                    isLoading = false,
                    errorMessage = "${currentStrings.analyzing} ${currentStrings.loss}: ${e.message}"
                )
            }
        }
    }

    private suspend fun performAiAnalysis(pgn: String, moves: List<ChessMove>): List<AnalysisItem> {
        // 获取当前语言代码
        val currentLanguageCode = LanguageManager.currentLanguageCode

        // 构建AI分析的问题，传入语言代码
        val question = buildAnalysisQuestion(pgn, moves, currentLanguageCode)

        // 调用AI服务（单参数版本）
        val aiResponse = aiService.aiReview(question)

        // 添加AI响应日志
        Log.d("AiAnalysis", "${currentStrings.aiResponse}: $aiResponse")
        Log.d("AiAnalysis", "当前语言: $currentLanguageCode")

        // 解析AI响应
        val parsedResults = parseAiResponse(aiResponse, moves, currentStrings)

        return parsedResults
    }

    private fun buildAnalysisQuestion(
        pgn: String,
        moves: List<ChessMove>,
        languageCode: String
    ): String {
        return PromptTemplates.buildAnalysisQuestion(pgn, moves, languageCode)
    }


    private fun parseAiResponse(aiResponse: String, moves: List<ChessMove>, strings: StringResources): List<AnalysisItem> {
        val analysisItems = mutableListOf<AnalysisItem>()

        // 按行分割
        val lines = aiResponse.split('\n')
            .map { it.trim() }
            .filter { it.isNotBlank() }

        // 创建一个从棋步到分析的映射
        val analysisMap = mutableMapOf<String, String>()

        // 简单的正则匹配：数字 + . 或 ... + 空格 + 棋步 + 空格 + 分析内容
        val movePattern = """(\d+\.(\.\.)?)\s+(\S+)\s+(.*)""".toRegex()

        lines.forEach { line ->
            val match = movePattern.find(line)
            if (match != null) {
                val (moveNumber, _, chessMove, analysis) = match.destructured
                val key = "$moveNumber $chessMove".trim()
                analysisMap[key] = analysis.trim()
                Log.d("AiAnalysis", "Parsed: $key -> ${analysis.take(50)}...")
            }
        }

        // 为每个棋步分配分析
        moves.forEach { move ->
            val moveKey = "${move.moveNumber}.${if (move.isWhite) "" else ".."} ${move.notation}"
            val alternativeKey1 = "${move.moveNumber}. ${move.notation}"
            val alternativeKey2 = "${move.moveNumber}... ${move.notation}"

            val analysis = when {
                analysisMap.containsKey(moveKey) -> analysisMap[moveKey]!!
                analysisMap.containsKey(alternativeKey1) -> analysisMap[alternativeKey1]!!
                analysisMap.containsKey(alternativeKey2) -> analysisMap[alternativeKey2]!!
                else -> {
                    // 尝试查找包含这个棋步的任何行
                    val found = analysisMap.entries.find { it.key.contains(move.notation) }
                    found?.value ?: strings.noAnalysis
                }
            }

            analysisItems.add(
                AnalysisItem(
                    moveNumber = move.moveNumber,
                    isWhiteMove = move.isWhite,
                    move = move.notation,
                    analysis = analysis
                )
            )
        }

        return analysisItems
    }

    fun onMoveNavigation(navigation: MoveNavigation) {
        val newIndex = when (navigation) {
            MoveNavigation.FIRST -> 0
            MoveNavigation.PREVIOUS -> state.currentMoveIndex - 1
            MoveNavigation.NEXT -> state.currentMoveIndex + 1
            MoveNavigation.LAST -> allBoardStates.size - 1
        }.coerceIn(0, allBoardStates.size - 1)

        // 计算高亮的分析项索引
        val highlightedIndex = calculateHighlightedAnalysisIndex(newIndex)

        state = state.copy(
            currentMoveIndex = newIndex,
            currentBoardState = allBoardStates[newIndex],
            highlightedMoveIndex = highlightedIndex
        )
    }

    /**
     * 根据当前棋盘状态索引计算应该高亮的分析项索引
     */
    private fun calculateHighlightedAnalysisIndex(boardIndex: Int): Int {
        return when {
            boardIndex == 0 -> 0 // 初始状态，高亮第一步分析
            boardIndex <= allMoves.size -> boardIndex - 1 // 正常移动，对应分析项索引
            else -> allMoves.size - 1 // 超出范围，高亮最后一步分析
        }.coerceIn(0, allMoves.size - 1)
    }

    /**
     * 直接从分析列表中选择某个分析项
     */
    fun onAnalysisItemSelected(index: Int) {
        if (index in 0 until allMoves.size) {
            // 分析项索引对应棋盘状态索引需要+1（因为棋盘状态包含初始状态）
            val boardIndex = index + 1
            if (boardIndex < allBoardStates.size) {
                state = state.copy(
                    currentMoveIndex = boardIndex,
                    currentBoardState = allBoardStates[boardIndex],
                    highlightedMoveIndex = index
                )
            }
        }
    }

    private fun updateAnalyzeButtonState() {
        val isEnabled = when (state.selectedInputMethod) {
            InputMethod.RECORD -> state.selectedRecord != null
            InputMethod.TEXT -> state.pgnText.isNotBlank()
        }
        state = state.copy(isAnalyzeEnabled = isEnabled)
    }

    private fun createInitialBoard(): List<List<ChessPiece?>> {
        return List(8) { row ->
            List(8) { col ->
                val position = Position(row, col)
                when (row) {
                    0 -> when (col) {
                        0, 7 -> ChessPiece(PieceType.ROOK, Player.BLACK, position)
                        1, 6 -> ChessPiece(PieceType.KNIGHT, Player.BLACK, position)
                        2, 5 -> ChessPiece(PieceType.BISHOP, Player.BLACK, position)
                        3 -> ChessPiece(PieceType.QUEEN, Player.BLACK, position)
                        4 -> ChessPiece(PieceType.KING, Player.BLACK, position)
                        else -> null
                    }

                    1 -> ChessPiece(PieceType.PAWN, Player.BLACK, position)
                    6 -> ChessPiece(PieceType.PAWN, Player.WHITE, position)
                    7 -> when (col) {
                        0, 7 -> ChessPiece(PieceType.ROOK, Player.WHITE, position)
                        1, 6 -> ChessPiece(PieceType.KNIGHT, Player.WHITE, position)
                        2, 5 -> ChessPiece(PieceType.BISHOP, Player.WHITE, position)
                        3 -> ChessPiece(PieceType.QUEEN, Player.WHITE, position)
                        4 -> ChessPiece(PieceType.KING, Player.WHITE, position)
                        else -> null
                    }

                    else -> null
                }
            }
        }
    }

    private fun parsePGNToBoardStates(pgn: String): List<List<List<ChessPiece?>>> {
        val boardStates = mutableListOf<List<List<ChessPiece?>>>()

        // 添加初始棋盘状态
        var currentBoard = createInitialBoard()
        boardStates.add(currentBoard)

        if (pgn.isBlank()) {
            return boardStates
        }

        val moves = parsePGNToMoves(pgn)

        for (move in moves) {
            currentBoard = applyMoveToBoard(currentBoard, move)
            boardStates.add(currentBoard)
        }

        return boardStates
    }

    private fun parsePGNToMoves(pgn: String): List<ChessMove> {
        val moves = mutableListOf<ChessMove>()

        // 清理PGN字符串，移除结果标记和多余空格
        val cleanPgn = pgn.replace("1/2-1/2", "")
            .replace("1-0", "")
            .replace("0-1", "")
            .replace("+", "")
            .replace("#", "")
            .trim()

        // 使用正则表达式匹配移动
        val moveRegex = """(\d+)\.\s*(\S+)\s+(\S+)""".toRegex()
        val matches = moveRegex.findAll(cleanPgn)

        for (match in matches) {
            val (moveNumber, whiteMove, blackMove) = match.destructured
            moves.add(ChessMove(moveNumber.toInt(), true, whiteMove))
            moves.add(ChessMove(moveNumber.toInt(), false, blackMove))
        }

        // 处理可能的单步（如果白棋走了但黑棋没走）
        if (moves.isEmpty()) {
            val singleMoveRegex = """(\d+)\.\s*(\S+)(?:\s+\S+)?""".toRegex()
            val singleMatches = singleMoveRegex.findAll(cleanPgn)

            for (match in singleMatches) {
                val (moveNumber, move) = match.destructured
                moves.add(ChessMove(moveNumber.toInt(), true, move))
            }
        }

        return moves
    }

    private fun applyMoveToBoard(
        board: List<List<ChessPiece?>>,
        move: ChessMove
    ): List<List<ChessPiece?>> {
        val newBoard = board.map { it.toMutableList() }.toMutableList()
        val player = if (move.isWhite) Player.WHITE else Player.BLACK

        try {
            when {
                move.notation == "O-O" || move.notation == "0-0" -> {
                    // 短易位
                    applyCastling(newBoard, player, true)
                }

                move.notation == "O-O-O" || move.notation == "0-0-0" -> {
                    // 长易位
                    applyCastling(newBoard, player, false)
                }

                move.notation.contains("=") -> {
                    // 兵升变
                    applyPromotionMove(newBoard, move, player)
                }

                else -> {
                    // 普通移动（包括吃子）
                    applyStandardMove(newBoard, move, player)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return newBoard
    }

    private fun applyCastling(
        board: MutableList<MutableList<ChessPiece?>>,
        player: Player,
        isKingside: Boolean
    ) {
        val row = if (player == Player.WHITE) 7 else 0

        if (isKingside) {
            // 移动王
            board[row][4] = null
            board[row][6] = ChessPiece(PieceType.KING, player, Position(row, 6))
            // 移动车
            board[row][7] = null
            board[row][5] = ChessPiece(PieceType.ROOK, player, Position(row, 5))
        } else {
            // 移动王
            board[row][4] = null
            board[row][2] = ChessPiece(PieceType.KING, player, Position(row, 2))
            // 移动车
            board[row][0] = null
            board[row][3] = ChessPiece(PieceType.ROOK, player, Position(row, 3))
        }
    }

    private fun applyPromotionMove(
        board: MutableList<MutableList<ChessPiece?>>,
        move: ChessMove,
        player: Player
    ) {
        val parts = move.notation.split("=")
        val movePart = parts[0].replace("x", "")
        val promotionPiece = when (parts[1]) {
            "Q" -> PieceType.QUEEN
            "R" -> PieceType.ROOK
            "B" -> PieceType.BISHOP
            "N" -> PieceType.KNIGHT
            else -> PieceType.QUEEN
        }

        val targetPos = algebraicToPosition(movePart.takeLast(2)) ?: return

        // 简化的实现：找到要升变的兵
        val pawnRow = if (player == Player.WHITE) 1 else 6
        val pawnCol = when (movePart[0]) {
            in 'a'..'h' -> algebraicFileToCol(movePart[0])
            else -> targetPos.col
        }

        // 移除兵，放置升变后的棋子
        board[pawnRow][pawnCol] = null
        board[targetPos.row][targetPos.col] = ChessPiece(promotionPiece, player, targetPos)
    }

    private fun applyStandardMove(
        board: MutableList<MutableList<ChessPiece?>>,
        move: ChessMove,
        player: Player
    ) {
        val cleanNotation = move.notation.replace("x", "").replace("+", "").replace("#", "")
        val targetPos = algebraicToPosition(cleanNotation.takeLast(2)) ?: return

        val pieceType = when {
            cleanNotation.startsWith("K") -> PieceType.KING
            cleanNotation.startsWith("Q") -> PieceType.QUEEN
            cleanNotation.startsWith("R") -> PieceType.ROOK
            cleanNotation.startsWith("N") -> PieceType.KNIGHT
            cleanNotation.startsWith("B") -> PieceType.BISHOP
            else -> PieceType.PAWN
        }

        // 找到移动的棋子
        val fromPosition = findPieceToMove(board, pieceType, player, targetPos, cleanNotation)
        if (fromPosition != null) {
            // 移动棋子
            val piece = board[fromPosition.row][fromPosition.col]
            board[fromPosition.row][fromPosition.col] = null
            board[targetPos.row][targetPos.col] = piece?.copy(position = targetPos)
        }
    }

    private fun findPieceToMove(
        board: MutableList<MutableList<ChessPiece?>>,
        pieceType: PieceType,
        player: Player,
        targetPos: Position,
        notation: String
    ): Position? {
        // 简化的实现：根据棋子类型和位置找到要移动的棋子
        for (row in 0 until 8) {
            for (col in 0 until 8) {
                val piece = board[row][col]
                if (piece?.player == player && piece.type == pieceType) {
                    // 对于兵移动，检查起始列
                    if (pieceType == PieceType.PAWN) {
                        if (notation.length == 2) {
                            // 简单的兵移动，如 "e4"
                            val fileChar = notation[0]
                            if (algebraicFileToCol(fileChar) == col) {
                                return Position(row, col)
                            }
                        }
                    } else {
                        // 对于其他棋子，返回第一个找到的合适棋子
                        return Position(row, col)
                    }
                }
            }
        }
        return null
    }

    private fun algebraicToPosition(algebraic: String): Position? {
        if (algebraic.length != 2) return null

        val file = algebraic[0]
        val rank = algebraic[1]

        val col = algebraicFileToCol(file)
        val row = algebraicRankToRow(rank)

        return if (col != -1 && row != -1) Position(row, col) else null
    }

    private fun algebraicFileToCol(file: Char): Int {
        return when (file) {
            'a' -> 0
            'b' -> 1
            'c' -> 2
            'd' -> 3
            'e' -> 4
            'f' -> 5
            'g' -> 6
            'h' -> 7
            else -> -1
        }
    }

    private fun algebraicRankToRow(rank: Char): Int {
        return when (rank) {
            '8' -> 0
            '7' -> 1
            '6' -> 2
            '5' -> 3
            '4' -> 4
            '3' -> 5
            '2' -> 6
            '1' -> 7
            else -> -1
        }
    }
}

data class AnalysisState(
    val selectedInputMethod: InputMethod = InputMethod.RECORD,
    val gameRecords: List<GameRecordEntity> = emptyList(),
    val selectedRecord: GameRecordEntity? = null,
    val pgnText: String = "",
    val isAnalyzeEnabled: Boolean = false,
    val isLoading: Boolean = false,
    val showChessboard: Boolean = false,
    val showAnalysis: Boolean = false,
    val analysisResults: List<AnalysisItem> = emptyList(),
    val moves: List<AnalysisItem> = emptyList(),
    val currentMoveIndex: Int = 0,
    val currentBoardState: List<List<ChessPiece?>> = emptyList(),
    val highlightedMoveIndex: Int = 0,
    val errorMessage: String? = null
)

enum class InputMethod {
    RECORD, TEXT
}

enum class MoveNavigation {
    FIRST, PREVIOUS, NEXT, LAST
}

data class AnalysisItem(
    val moveNumber: Int,
    val isWhiteMove: Boolean,
    val move: String,
    val analysis: String
)

data class ChessMove(
    val moveNumber: Int,
    val isWhite: Boolean,
    val notation: String
)